import { reactive } from 'vue'
import { copyObjectDeep } from '../utils/normalUtils'
import { sendServiceData } from '../service'

/**
 * 分页数据对象
 */
export type TPageData = {
    isLoading: boolean,
    dataSource: any,
    total: number,
    pageSizeList: number[],
    length: number,
    pageIndex: number
}

/**
 * 分页查询模型 简单写 不整体封装了
 */
export class PageQuery {
    // 查询方法
    queryMethod:any = null

    queryHandler:any = null

    resultListHandler:any = null

    resultItemHandler:any = null

    /**
     * 所有处理完回调函数 fixed
     */
    endHandler:any = null

    pageData:any = reactive({
        isLoading: false,
        dataSource: [],
        total: 1,
        pageSizeList: [20, 50, 100, 150, 200],

        length: 50,
        pageIndex: 1
    })

    search = null

    catchSend:any = null

    catchMode = false

    hasLast = false

    // 优先清理数据
    firstClear = false

    constructor(options:any = null) {
        if (options) {
            this.queryMethod = options.queryMethod || null
            this.queryHandler = options.queryHandler || null
            this.resultListHandler = options.resultListHandler || null
            this.endHandler = options.endHandler || null
            if (options.search) this.search = options.search
            if (Object.prototype.hasOwnProperty.call(options, 'catchMode')) this.catchMode = options.catchMode
            if (Object.prototype.hasOwnProperty.call(options, 'pageData'))Object.assign(this.pageData, options.pageData || {})
        }
    }

    /**
     * 查列表
     * @param params
     * @param resultHandler
     * @param itemHandler
     * @param endHandler
     */
    async queryList(params:any = null, resultHandler:any = null, itemHandler:any = null, endHandler:any = null) {
        if (resultHandler) this.resultListHandler = resultHandler
        if (itemHandler) this.resultItemHandler = itemHandler
        if (endHandler) this.endHandler = endHandler
        this.hasLast = false
        this.pageData.pageIndex = 1
        this.pageData.total = 0
        if (this.firstClear) this.pageData.dataSource = []
        await this.executeQuery(params, true)
    }

    /**
     * 执行查询
     * @param params
     * @param reset
     */
    async executeQuery(params:any, reset = false) {
        this.catchSend = params ? copyObjectDeep(params, 1) : copyObjectDeep(this.search || {}, 1)
        this.catchSend.length = this.pageData.length
        this.catchSend.pageIndex = this.pageData.pageIndex
        if (this.queryHandler) this.catchSend = this.queryHandler(this.catchSend)
        const result = await sendServiceData(this.queryMethod, this.catchSend, this.pageData)
        let list:any[] = []
        if (this.resultListHandler) list = this.resultListHandler(result)
        else list = this.initResultList(result)
        this.hasLast = list.length < this.pageData.index
        if (this.resultItemHandler && list && list.length > 0)list.forEach((item) => this.resultItemHandler(item))
        if (this.catchMode && !reset) {
            if (!this.pageData.dataSource) this.pageData.dataSource = []
            this.pageData.dataSource.push(...list)
        } else {
            this.pageData.dataSource = list || []
        }
        this.pageData.total = result.total
        if (this.endHandler) this.endHandler(this.pageData)
    }

    /**
     * 页数变化处理
     */
    async pageChange() {
        this.executeQuery(this.catchSend)
    }

    /**
     * 重新查询
     */
    async reQuery() {
        await this.queryList(this.catchSend)
    }

    /**
     * 下一页
     */
    async next() {
        if (this.hasLast ||
            this.pageData.dataSource.length === 0 ||
            this.pageData.total <= this.pageData.dataSource.length) return
        this.pageData.pageIndex += 1
        await this.executeQuery(this.catchSend)
    }

    /**
     *
     * @param result
     */
    initResultList(result:any) {
        return result.records || []
    }

    /**
     *
     * @param result
     */
    initResultTotal(result:any) {
         return result.total || 0
    }
}

export function usePageQuery(options:any) {
    const query = new PageQuery(options)
    return { actions: query, pageData: query.pageData, pagePm: query }
}
